<?php

/**
 * Kumbia PHP Framework
 *
 * LICENSE
 *
 * This source file is subject to the GNU/GPL that is bundled
 * with this package in the file docs/LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.kumbia.org/license.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to kumbia@kumbia.org so we can send you a copy immediately.
 *
 * @category   Kumbia
 * @package Date
 * @copyright Copyright (c) 2008-2008 Andres Felipe Gutierrez (andresfelipe at vagoogle.net)
 * @license    http://www.kumbia.org/license.txt GNU/GPL
 */

class Date {

	/**
	 * Valor interno de fecha
	 *
	 * @var string
	 */
	private $date;

	/**
	 * Valor interno del Dia
	 *
	 * @var string
	 */
	private $day;

	/**
	 * Valor interno del A&ntilde;o
	 *
	 * @var string
	 */
	private $year;

	/**
	 * Valor interno del Mes
	 *
	 * @var string
	 */
	private $month;

	/**
	 * Valor interno del Mes
	 *
	 * @var string
	 */
	private $timestamp;

	/**
	 * Crea un objeto de fecha Date
	 *
	 */
	public function __construct($date=""){
		if($date){
			$date_parts = explode("-", $date);
			$this->year = (int) $date_parts[0];
			$this->month = (int) $date_parts[1];
			$this->day = (int) $date_parts[2];
			$this->date = $date;
			$this->timestamp = mktime(0, 0, 0, $this->month, $this->day, $this->year);
		} else {
			$this->year = date("Y");
			$this->month = date("m");
			$this->day = date("d");
			$this->timestamp = time;
			$this->date = $this->year."-".sprintf("%02s", $this->month)."-".sprintf("%02s", $this->day);
		}
	}

	/**
	 * Devuelve el nombre del mes de la fecha interna
	 *
	 * @return string
	 */
	public function getMonthName(){
		return ucfirst(strftime("%B", $this->timestamp));
	}

	/**
	 * Devuelve el nombre abreviado del mes de la fecha interna
	 *
	 * @return string
	 */
	public function getAbrevMonthName(){
		return ucfirst(strftime("%b", $this->timestamp));
	}

	/**
	 * Devuelve el dia interno de la fecha
	 *
	 * @return string
	 */
	public function getDay(){
		return $this->day;
	}

	/**
	 * Devuelve el mes interno de la fecha
	 *
	 * @return string
	 */
	public function getMonth(){
		return $this->month;
	}

	/**
	 * Devuelve el a#o interno de la fecha
	 *
	 * @return string
	 */
	public function getYear(){
		return $this->year;
	}

	/**
	 * Devuelve el timestamp de la fecha interna
	 *
	 */
	public function getTimestamp(){
		return $this->timestamp;
	}

	/**
	 * Devuelve la fecha en string
	 *
	 * @return string
	 */
	public function __toString(){
		return $this->date;
	}

	/**
	 * Suma meses a la fecha interna
	 *
	 */
	public function addMonths($month){
		if($this->month+$month>12){
			$this->month = ($month%12)+1;
			$this->year+=((int)($month/12));
		} else {
			$this->month++;
		}
		$this->date = $this->year."-".sprintf("%02s", $this->month)."-".sprintf("%02s", $this->day);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Resta meses a la fecha interna
	 *
	 */
	public function diffMonths($month){
		if($this->month-$month<1){
			$this->month = 12-(($month%12)+1);
			$this->year-=((int)($month/12));
		} else {
			$this->month--;
		}
		$this->date = $this->year."-".sprintf("%02s", $this->month)."-".sprintf("%02s", $this->day);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Suma numero dias a la fecha actual
	 *
	 * @param integer $days
	 * @return string
	 */
	public function addDays($days){
		$this->date = date("Y-m-d", $this->timestamp+$days*86400);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Resta numero dias a la fecha actual
	 *
	 * @param integer $days
	 * @return string
	 */
	public function diffDays($days){
		$this->date = date("Y-m-d", $this->timestamp-$days*86400);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Suma un numero de a#os a la fecha interna
	 *
	 * @param numeric $years
	 * @return string
	 */
	public function addYears($years){
		$this->year+=$years;
		$this->date = $this->year."-".sprintf("%02s", $this->month)."-".sprintf("%02s", $this->day);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Resta un numero de a#os a la fecha interna
	 *
	 * @param numeric $years
	 * @return string
	 */
	public function diffYears($years){
		$this->year-=$years;
		$this->date = $this->year."-".sprintf("%02s", $this->month)."-".sprintf("%02s", $this->day);
		$this->consolideDate();
		return $this->date;
	}

	/**
	 * Obtener usando un formato
	 *
	 * @param $format
	 */
	public function getUsingFormat($format){
		$datetime = new DateTime($this->date);
		return $datetime->format($format);
	}

	/**
	 * Devuelve el nombre del dia de la semana
	 *
	 * @return string
	 */
	public function getDayOfWeek(){
		$datetime = new DateTime($this->date);
		return $datetime->format("l");
	}

	/**
	 * Resta una fecha de otra
	 *
	 */
	public function diffDate($date){
		$date_parts = explode("-", $date);
		$year = (int) $date_parts[0];
		$month = (int) $date_parts[1];
		$day = (int) $date_parts[2];
		$timestamp = mktime(0, 0, 0, $month, $day, $year);
		return (int) (($this->timestamp-$timestamp)/86400);
	}

	/**
	 * Devuelve true si la fecha interna es la de hoy
	 *
	 * @return boolean
	 */
	public function isToday(){
		if($this->date==date("Y-m-d")){
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Devuelve true si la fecha interna es la de ayer
	 *
	 * @return boolean
	 */
	public function isYesterday(){
		if(!isset($this->yesterday)){
			$time = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
			$this->yesterday = $time-86400;
		}
		if($this->timestamp==$this->yesterday){
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Devuelve true si la fecha interna es la de ma#ana
	 *
	 * @return boolean
	 */
	public function isTomorrow(){
		if(!isset($this->tomorrow)){
			$time = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
			$this->tomorrow = $time-86400;
		}
		if($this->timestamp==$this->tomorrow){
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Consolida los valores internos de la fecha
	 *
	 */
	private function consolideDate(){
		$date_parts = explode("-", $this->date);
		$this->year = (int) $date_parts[0];
		$this->month = (int) $date_parts[1];
		$this->day = (int) $date_parts[2];
		$this->timestamp = mktime(0, 0, 0, $this->month, $this->day, $this->year);
	}

}

?>